/**
 * 安全配置和防护措施
 * 
 * 包含 XSS 防护、CSRF 防护、内容安全策略等
 */

import { NextRequest, NextResponse } from 'next/server'

// XSS 防护 - HTML 实体编码
export function escapeHtml(text: string): string {
  const map: { [key: string]: string } = {
    '&': '&amp;',
    '<': '&lt;',
    '>': '&gt;',
    '"': '&quot;',
    "'": '&#39;',
    '/': '&#x2F;',
    '`': '&#x60;',
    '=': '&#x3D;'
  }
  
  return text.replace(/[&<>"'`=\/]/g, (s) => map[s])
}

// 清理用户输入 - 移除危险字符
export function sanitizeInput(input: string): string {
  return input
    // 移除 script 标签
    .replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '')
    // 移除 iframe 标签
    .replace(/<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi, '')
    // 移除 object 标签
    .replace(/<object\b[^<]*(?:(?!<\/object>)<[^<]*)*<\/object>/gi, '')
    // 移除 embed 标签
    .replace(/<embed\b[^<]*(?:(?!<\/embed>)<[^<]*)*<\/embed>/gi, '')
    // 移除 link 标签
    .replace(/<link\b[^<]*(?:(?!<\/link>)<[^<]*)*<\/link>/gi, '')
    // 移除 style 标签
    .replace(/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/gi, '')
    // 移除 javascript: 协议
    .replace(/javascript:/gi, '')
    // 移除 data: 协议（除了图片）
    .replace(/data:(?!image\/)/gi, '')
    // 移除 vbscript: 协议
    .replace(/vbscript:/gi, '')
    // 移除 on* 事件处理器
    .replace(/\s*on\w+\s*=\s*["'][^"']*["']/gi, '')
    .trim()
}

// URL 验证和清理
export function sanitizeUrl(url: string): string | null {
  try {
    const parsed = new URL(url)
    
    // 只允许 HTTP 和 HTTPS 协议
    if (!['http:', 'https:'].includes(parsed.protocol)) {
      return null
    }
    
    // 检查是否为恶意域名（简单黑名单）
    const maliciousDomains = [
      'malware.com',
      'phishing.com',
      // 可以添加更多恶意域名
    ]
    
    if (maliciousDomains.some(domain => parsed.hostname.includes(domain))) {
      return null
    }
    
    return parsed.toString()
  } catch {
    return null
  }
}

// 文件名安全检查
export function sanitizeFileName(fileName: string): string {
  return fileName
    // 移除路径遍历字符
    .replace(/\.\./g, '')
    .replace(/[\/\\]/g, '')
    // 移除特殊字符
    .replace(/[<>:"|?*]/g, '')
    // 限制长度
    .substring(0, 255)
    .trim()
}

// 内容安全策略 (CSP) 头
export function getCSPHeader(): string {
  const csp = [
    "default-src 'self'",
    "script-src 'self' 'unsafe-inline' 'unsafe-eval' https://vercel.live https://va.vercel-scripts.com",
    "style-src 'self' 'unsafe-inline' https://fonts.googleapis.com",
    "font-src 'self' https://fonts.gstatic.com",
    "img-src 'self' data: https: blob:",
    "media-src 'self' https:",
    "object-src 'none'",
    "base-uri 'self'",
    "form-action 'self'",
    "frame-ancestors 'none'",
    "upgrade-insecure-requests"
  ].join('; ')
  
  return csp
}

// 安全头中间件
export function addSecurityHeaders(response: NextResponse): NextResponse {
  // 内容安全策略
  response.headers.set('Content-Security-Policy', getCSPHeader())
  
  // XSS 防护
  response.headers.set('X-XSS-Protection', '1; mode=block')
  
  // 内容类型嗅探防护
  response.headers.set('X-Content-Type-Options', 'nosniff')
  
  // 点击劫持防护
  response.headers.set('X-Frame-Options', 'DENY')
  
  // 强制 HTTPS
  if (process.env.NODE_ENV === 'production') {
    response.headers.set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains')
  }
  
  // 引用者策略
  response.headers.set('Referrer-Policy', 'strict-origin-when-cross-origin')
  
  // 权限策略
  response.headers.set('Permissions-Policy', 'camera=(), microphone=(), geolocation=()')
  
  return response
}

// CSRF Token 生成和验证
export class CSRFProtection {
  private static readonly SECRET = process.env.CSRF_SECRET || 'default-csrf-secret'
  
  static generateToken(sessionId: string): string {
    const crypto = require('crypto')
    const timestamp = Date.now().toString()
    const data = `${sessionId}:${timestamp}`
    const hash = crypto.createHmac('sha256', this.SECRET).update(data).digest('hex')
    return `${timestamp}:${hash}`
  }
  
  static validateToken(token: string, sessionId: string): boolean {
    try {
      const [timestamp, hash] = token.split(':')
      const data = `${sessionId}:${timestamp}`
      const expectedHash = require('crypto').createHmac('sha256', this.SECRET).update(data).digest('hex')
      
      // 检查哈希是否匹配
      if (hash !== expectedHash) {
        return false
      }
      
      // 检查时间戳是否在有效期内（1小时）
      const tokenTime = parseInt(timestamp)
      const now = Date.now()
      const maxAge = 60 * 60 * 1000 // 1小时
      
      return (now - tokenTime) <= maxAge
    } catch {
      return false
    }
  }
}

// SQL 注入防护（虽然我们使用 Prisma，但额外的防护总是好的）
export function sanitizeSQLInput(input: string): string {
  return input
    .replace(/['";\\]/g, '') // 移除 SQL 特殊字符
    .replace(/--/g, '') // 移除 SQL 注释
    .replace(/\/\*/g, '') // 移除 SQL 块注释开始
    .replace(/\*\//g, '') // 移除 SQL 块注释结束
    .replace(/\bUNION\b/gi, '') // 移除 UNION 关键字
    .replace(/\bSELECT\b/gi, '') // 移除 SELECT 关键字
    .replace(/\bINSERT\b/gi, '') // 移除 INSERT 关键字
    .replace(/\bUPDATE\b/gi, '') // 移除 UPDATE 关键字
    .replace(/\bDELETE\b/gi, '') // 移除 DELETE 关键字
    .replace(/\bDROP\b/gi, '') // 移除 DROP 关键字
    .trim()
}

// 密码强度检查
export function checkPasswordStrength(password: string): {
  isStrong: boolean
  score: number
  feedback: string[]
} {
  const feedback: string[] = []
  let score = 0
  
  // 长度检查
  if (password.length >= 8) {
    score += 1
  } else {
    feedback.push('密码至少需要8个字符')
  }
  
  if (password.length >= 12) {
    score += 1
  }
  
  // 字符类型检查
  if (/[a-z]/.test(password)) {
    score += 1
  } else {
    feedback.push('密码需要包含小写字母')
  }
  
  if (/[A-Z]/.test(password)) {
    score += 1
  } else {
    feedback.push('密码需要包含大写字母')
  }
  
  if (/\d/.test(password)) {
    score += 1
  } else {
    feedback.push('密码需要包含数字')
  }
  
  if (/[!@#$%^&*(),.?":{}|<>]/.test(password)) {
    score += 1
  } else {
    feedback.push('密码建议包含特殊字符')
  }
  
  // 常见密码检查
  const commonPasswords = [
    'password', '123456', 'password123', 'admin', 'qwerty',
    '12345678', '123456789', 'password1', 'abc123', 'Password1'
  ]
  
  if (commonPasswords.includes(password.toLowerCase())) {
    score = 0
    feedback.push('请不要使用常见密码')
  }
  
  return {
    isStrong: score >= 4,
    score,
    feedback
  }
}

// 邮箱验证
export function isValidEmail(email: string): boolean {
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
  return emailRegex.test(email) && email.length <= 254
}

// IP 地址获取
export function getClientIP(request: NextRequest): string {
  const forwarded = request.headers.get('x-forwarded-for')
  const realIP = request.headers.get('x-real-ip')
  
  if (forwarded) {
    return forwarded.split(',')[0].trim()
  }
  
  if (realIP) {
    return realIP
  }
  
  return request.ip || 'unknown'
}

// 用户代理检查（检测可疑的爬虫或机器人）
export function isSuspiciousUserAgent(userAgent: string): boolean {
  const suspiciousPatterns = [
    /bot/i,
    /crawler/i,
    /spider/i,
    /scraper/i,
    /curl/i,
    /wget/i,
    /python/i,
    /java/i
  ]
  
  return suspiciousPatterns.some(pattern => pattern.test(userAgent))
}

// 导出安全工具集合
export const SecurityUtils = {
  escapeHtml,
  sanitizeInput,
  sanitizeUrl,
  sanitizeFileName,
  sanitizeSQLInput,
  checkPasswordStrength,
  isValidEmail,
  getClientIP,
  isSuspiciousUserAgent,
  CSRFProtection,
  addSecurityHeaders,
  getCSPHeader
}
